/***********************************************************************
	filename: 	CEGUIAnimatesetManager.cpp
	created:	21/2/2004
	author:		Paul D Turner
	
	purpose:	Implements the AnimatesetManager class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUIAnimatesetManager.h"
#include "CEGUIExceptions.h"
#include "CEGUILogger.h"
#include "CEGUIAnimateset.h"

// Start of CEGUI namespace section
namespace CEGUI
{
/*************************************************************************
	Static Data Definitions
*************************************************************************/
// singleton instance pointer
template<> AnimatesetManager* Singleton<AnimatesetManager>::ms_Singleton	= 0;


/*************************************************************************
	Constructor
*************************************************************************/
AnimatesetManager::AnimatesetManager(void)
{
	Logger::getSingleton().logEvent("CEGUI::AnimatesetManager singleton created");
}


/*************************************************************************
	Destructor
*************************************************************************/
AnimatesetManager::~AnimatesetManager(void)
{
	Logger::getSingleton().logEvent("---- Begining cleanup of Animateset system ----");

	destroyAllAnimatesets();

	Logger::getSingleton().logEvent("CEGUI::AnimatesetManager singleton destroyed");
}


/*************************************************************************
	Create an empty Animateset that has the given name and uses the
	given Texture
*************************************************************************/
Animateset* AnimatesetManager::createAnimateset(const String& name, Texture* texture)
{
	Logger::getSingleton().logEvent("Attempting to create Animateset '" + name +"' with texture only.");

	if (isAnimatesetPresent(name))
	{
		throw	AlreadyExistsException("AnimatesetManager::createAnimateset - An Animateset object named '" + name + "' already exists.");
	}

	Animateset* temp = new Animateset(name);
	d_animatesets[name] = temp;

	return temp;
}


/*************************************************************************
	Create an Animateset object from the specified file
*************************************************************************/
Animateset* AnimatesetManager::createAnimateset(const String& filename, const String& resourceGroup)
{
	Logger::getSingleton().logEvent("Attempting to create an Animateset from the information specified in file '" + filename + "'.");

	Animateset* temp = new Animateset(filename, resourceGroup);

	String	name = temp->getName();

	if (isAnimatesetPresent(name))
	{
		delete temp;

		throw	AlreadyExistsException("AnimatesetManager::createAnimateset - An Animateset object named '" + name + "' already exists.");
	}

	d_animatesets[name] = temp;

	return temp;
}

/*************************************************************************
	Destroys the Animateset with the specified name
*************************************************************************/
void AnimatesetManager::destroyAnimateset(const String& name)
{
	AnimatesetRegistry::iterator	pos = d_animatesets.find(name);

	if (pos != d_animatesets.end())
	{
		String tmpName(name);

		delete pos->second;
		d_animatesets.erase(pos);

		Logger::getSingleton().logEvent("Animateset '" + tmpName +"' has been destroyed.", Informative);
	}

}


/*************************************************************************
	Destroys the given Animateset object
*************************************************************************/
void AnimatesetManager::destroyAnimateset(Animateset* imageset)
{
	if (imageset)
	{
		destroyAnimateset(imageset->getName());
	}

}


/*************************************************************************
	Destroy all Animateset objects
*************************************************************************/
void AnimatesetManager::destroyAllAnimatesets(void)
{
	while (!d_animatesets.empty())
	{
		destroyAnimateset(d_animatesets.begin()->first);
	}
}

/*************************************************************************
	Returns a pointer to the Animateset object with the specified name
*************************************************************************/
Animateset* AnimatesetManager::getAnimateset(const String& name) const
{
	AnimatesetRegistry::const_iterator	pos = d_animatesets.find(name);

	if (pos == d_animatesets.end())
	{
		throw UnknownObjectException("AnimatesetManager::getAnimateset - No Animateset named '" + name + "' is present in the system.");
	}

	return pos->second;
}

/*************************************************************************
	Return a AnimatesetManager::AnimatesetIterator object to iterate over
	the available Animateset objects.
*************************************************************************/
AnimatesetManager::AnimatesetIterator AnimatesetManager::getIterator(void) const
{
	return AnimatesetIterator(d_animatesets.begin(), d_animatesets.end());
}


void AnimatesetManager::writeAnimatesetToStream(const String& imageset, OutStream& out_stream) const
{
    const Animateset* iset = getAnimateset(imageset);
    // Create an XMLSerializer which make use of 4 space and UTF-8 encoding 
    XMLSerializer xml(out_stream);
    iset->writeXMLToStream(xml);
}


} // End of  CEGUI namespace section
